package jblip.apps.clip;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import jblip.BlipClient;
import jblip.apps.clip.cmds.Bliposphere;
import jblip.apps.clip.cmds.ClipCommand;
import jblip.apps.clip.cmds.Delete;
import jblip.apps.clip.cmds.Get;
import jblip.apps.clip.cmds.GetAvatar;
import jblip.apps.clip.cmds.GetBackground;
import jblip.apps.clip.cmds.GetMovie;
import jblip.apps.clip.cmds.GetPictures;
import jblip.apps.clip.cmds.GetRecording;
import jblip.apps.clip.cmds.Msg;
import jblip.apps.clip.cmds.Poll;
import jblip.apps.clip.cmds.PollAll;
import jblip.apps.clip.cmds.PollDashboard;
import jblip.apps.clip.cmds.PollPictures;
import jblip.apps.clip.cmds.PollShortlinks;
import jblip.apps.clip.cmds.PollTag;
import jblip.apps.clip.cmds.PostPicture;
import jblip.apps.clip.cmds.Say;
import jblip.apps.clip.cmds.Subs;
import jblip.apps.clip.cmds.Whois;
import jblip.base.HttpClient;
import jblip.util.Base64Encoder;

public class Clip {
  private static final Map<String, ClipCommand> cmds;

  private static String BLIP_USER;

  private static String BLIP_PASS;

  private static String BLIP_HOST;

  static {
    cmds = new HashMap<String, ClipCommand>();
    addCommand(new Delete());
    addCommand(new Bliposphere());
    addCommand(new Poll());
    addCommand(new PollAll());
    addCommand(new PollDashboard());
    addCommand(new PollPictures());
    addCommand(new PollShortlinks());
    addCommand(new PollTag());
    addCommand(new Whois());
    addCommand(new Subs());
    addCommand(new Get());
    addCommand(new GetMovie());
    addCommand(new GetPictures());
    addCommand(new GetRecording());
    addCommand(new GetAvatar());
    addCommand(new GetBackground());
    addCommand(new Msg());
    addCommand(new Say());
    addCommand(new PostPicture());
  }

  private static void addCommand(ClipCommand cmd) {
    cmds.put(cmd.getName(), cmd);
  }

  private static void runcommand(BlipClient client, String name, String[] params) {
    // Some top-level functions, set, quit etc.
    if (name.equals("set")) {
      if (params.length == 2) {
        ClipCommand.setProperty(params[0], params[1]);
      } else {
        System.out.print("USAGE: ");
        System.out.println("set <variable> <value>");
      }
      return;
    } else if (name.equals("unset")) {
      if (params.length == 1) {
        ClipCommand.unsetProperty(params[0]);
      } else {
        System.out.print("USAGE: ");
        System.out.println("unset <variable>");
      }
      return;
    } else if (name.equals("quit")) {
      System.out.println("Bye.");
      System.exit(0);
    } else if (name.equals("creds")) {
      byte[] credentials;
      try {
        credentials = (BLIP_USER + ":" + BLIP_PASS).getBytes("UTF-8");
        System.out.println("Authorization: Basic "
            + Base64Encoder.encode(credentials));
      } catch (UnsupportedEncodingException e) {
      }
    }

    // commands from the set
    ClipCommand cmd = cmds.get(name);
    if (cmd == null) {
      System.out.println(name + ": no such command");
      return;
    }

    if (params.length < cmd.getRequiredArgsCount()
        || params.length > cmd.getMaximumArgsCount()) {
      System.out.print("USAGE: ");
      System.out.println(cmd.getName() + " " + cmd.getUsageMessage());
      return;
    }

    cmd.execute(client, params);
  }

  public static void main(String[] args) throws Exception {
    BLIP_USER = System.getenv("BLIP_USER");
    BLIP_PASS = System.getenv("BLIP_PASS");
    BLIP_HOST = System.getenv("BLIP_HOST");

    if (BLIP_USER == null) {
      BLIP_USER = "";
    }
    if (BLIP_PASS == null) {
      BLIP_PASS = "";
    }
    if (BLIP_HOST == null) {
      BLIP_HOST = "api.blip.pl";
    }

    BlipClient client = new HttpClient(BLIP_HOST, BLIP_USER, BLIP_PASS);

    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    while (true) {
      System.out.print(BLIP_USER + " # ");
      String next_input = input.readLine();
      if (next_input == null) {
        System.out.println("Bye!");
        input.close();
        return;
      }

      String[] nextline = next_input.split("\\s+");
      if (nextline[0].equals("")) {
        continue;
      } else if (nextline[0].startsWith("/")) {
        String[] params = Arrays.copyOfRange(nextline, 1, nextline.length);
        runcommand(client, nextline[0].substring(1), params);
      } else {
        System.out.println("Unknown command '" + nextline[0] + "'");
      }
    }
  }
}
